#ifndef EDGEMESH_HPP
#define EDGEMESH_HPP
#include "Mesh.hpp"
#include <assert.h>
// largely unused code here...

namespace EdgeMeshData
{
   class Edge;
   struct EdgeFace
   {
      Face  face;
      int   edges[3];
   };
   class EdgeEdge
   {
   public:
      int verts[2];
      void CopyPrivate()
      { 
         if (faceCount > 2)
         {
            int arraySize = extraFaces[0]+1;
            int* newArray = new int[arraySize];
            for (int i = 0; i < arraySize; ++i)
            {
               newArray[i] = extraFaces[i];
            }
            extraFaces = newArray;
         }
      }
      void DeletePrivate()
      {
         if (faceCount > 2)
         {
            delete extraFaces;
            extraFaces = 0;
            faceCount = 2;
         }
      }
   private:
   
      int faceCount;
      int faces[2];
      int* extraFaces;
   public:
      EdgeEdge() : faceCount(0), extraFaces(0) {}
      int size() { return faceCount; }

      int& operator[](int f)
      {
         if (f < 2) return faces[f];
         return extraFaces[f-1];
      }

      void RemoveFace(int f)
      {
         for (int i = 0; i < faceCount; ++i)
         {
            if ((*this)[i] == f)
            {
               RemoveIndex(i);
               return;
            }
         }
         assert(!"Face not found on edge!");
      }

      void AddFace(int f)
      {
         if (faceCount < 2)
         {
            faces[faceCount] = f;
         }
         else
         {
            if (faceCount == 2) 
            {
               GrowFaces();
            }
            else if (faceCount - 2 > extraFaces[0])
            {
               GrowFaces();
            }
            extraFaces[faceCount - 1] = f;
         }
         ++faceCount;
      }

   private:
      void RemoveIndex(int aIndex)
      {
         for (int i = aIndex + 1; i < faceCount; ++i)
         {
            (*this)[i-1] = (*this)[i];
         }
         --faceCount;
         if (faceCount == 2)
         {
            delete extraFaces;
            extraFaces = 0;
         }
      }
      void GrowFaces()
      {
         if (faceCount == 2)
         {
            extraFaces = new int[8];
            extraFaces[0] = 7;
         }
         else if (faceCount > 2)
         {
            int* newArray = new int[extraFaces[0] * 2];
            for (int i = 0; i < extraFaces[0] + 1; ++i)
            {
               newArray[i] = extraFaces[i];
            }
            delete extraFaces;
            extraFaces = newArray;
         }
      }
   };
}

class EdgeMesh
{
public:
   EdgeMesh(Mesh& aMesh);

   ~EdgeMesh();

   void GetMesh(Mesh& aMesh);

   void SplitEdge(int               aEdgeId,
                  std::vector<int>& aNewEdges);

   void SplitLargest();

   typedef std::vector<EdgeMeshData::EdgeEdge> EdgeList;
   typedef std::vector<EdgeMeshData::EdgeFace> FaceList;
   const EdgeList& GetEdges() const { return mEdges; }
   const FaceList& GetFace() const { return mFaces; }
   const std::vector<Vec3>& GetVerts() const { return mVerts; }

private:

   void SplitFace(EdgeMeshData::EdgeFace& aFace,
                  int                     aSplitEdge,
                  int                     aSplitEdge1,
                  int                     aSplitEdge2,
                  int                     aNewEdge,
                  int                     aNewVertex,
                  EdgeMeshData::EdgeFace& aNewFaceA,
                  EdgeMeshData::EdgeFace& aNewFaceB);

   void AddFaceEdgeP(int aFace,
                     int aEdgeId, int v1, int v2);
   void LinkFaceEdge(int aFace, int aEdgeId);
   void Check();
   std::vector<EdgeMeshData::EdgeEdge>  mEdges;
   std::vector<EdgeMeshData::EdgeFace>  mFaces;
   std::vector<Vec3>                    mVerts;
   int   mEdgeCount;


   
};
#endif